2015-08-01 iPhone vs. email standards
Introduction
When setting up a new iPhone, we want to configure an email account with a standard IMAP/SMTP provider. Eventually, we want the phone to receive email over IMAP port 143 using STARTTLS, and to send email over SMTP port 587 using SMTP AUTH, again with STARTTLS.
tl;dr - During setup, the phone will attempt a raw SSL connection to port 587 on the mail server. That probe may trigger adaptive firewalls and result in the phone losing all connectivity to the mail server.
For details on IMAP, you might want to read rfc3501. For details on SMTP, you might want to read rfc5321.
Environment
The phone (iPhone 5 MD658LL/A; iOS 8.4 12H143) is connected to the local network via wifi. The local dhcp server hands out two dns servers, one of which is also the target mail server. We run tcpdump on both servers during the phone setup process to capture details of all the dns queries and mail server probes from the phone.
tcpdump -w /tmp/$(hostname).log host $phone_address
Setup screen 1 - New Account
There was no opportunity to change any of the server port numbers or SSL settings - all of that is automatically determined by probing when you hit 'next' from this New Account screen. It does the obvious DNS lookups for the A and AAAA records for the mail server, but it does not do lookups for any other types such as SRV or TLSA in the domain of the mail server (five-ten-sg.com) or the domain of the account (tesley.org).
** probe imap port 993 16:20:38.971980 IP 205.147.40.48.52673 > 205.147.40.34.993: Flags [S], seq 2654641439, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085757345 ecr 0,sackOK,eol], length 0 ** probe smtp port 587 with ssl handshake 16:20:39.899364 IP 205.147.40.48.52674 > 205.147.40.34.587: Flags [S], seq 2914672390, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085758251 ecr 0,sackOK,eol], length 0 Jul 31 16:20:41 ns sendmail[21383]: NOQUEUE: connect from host48.byington.org [205.147.40.48] Jul 31 16:20:41 ns sendmail[21383]: t6VNKfw7021383: rejecting commands from host48.byington.org [205.147.40.48] due to pre-greeting traffic after 0 seconds Jul 31 16:20:41 ns sendmail[21383]: t6VNKfw7021383: --- 554 ns.five-ten-sg.com ESMTP not accepting messages Jul 31 16:20:41 ns sendmail[21383]: t6VNKfw7021383: <-- \026\003\001 Jul 31 16:20:41 ns sendmail[21383]: t6VNKfw7021383: Sending "\026\003\001" to Milter Jul 31 16:21:09 ns sendmail[21383]: t6VNKfw7021383: --- 421 4.4.1 ns.five-ten-sg.com Lost input channel from host48.byington.org [205.147.40.48] Jul 31 16:21:09 ns sendmail[21383]: t6VNKfw7021383: lost input channel from host48.byington.org [205.147.40.48] to MSA after startup ** probe smtp port 587 with proper starttls 16:21:09.929801 IP 205.147.40.48.52675 > 205.147.40.34.587: Flags [S], seq 1337181470, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085788254 ecr 0,sackOK,eol], length 0 Jul 31 16:21:09 ns sendmail[21422]: NOQUEUE: connect from host48.byington.org [205.147.40.48] Jul 31 16:21:10 ns sendmail[21422]: t6VNL9uw021422: <-- EHLO [205.147.40.48] Jul 31 16:21:10 ns sendmail[21422]: t6VNL9uw021422: --- 250-ns.five-ten-sg.com Hello host48.byington.org [205.147.40.48], pleased to meet you Jul 31 16:21:10 ns sendmail[21422]: STARTTLS=server, relay=host48.byington.org [205.147.40.48], version=TLSv1/SSLv3, verify=NO, cipher=DHE-RSA-AES256-SHA, bits=256/256 Jul 31 16:21:10 ns sendmail[21422]: t6VNL9uw021422: <-- EHLO [205.147.40.48] Jul 31 16:21:10 ns sendmail[21422]: t6VNL9ux021422: --- 250-ns.five-ten-sg.com Hello host48.byington.org [205.147.40.48], pleased to meet you
Setup screen 2 - Save
This screen appears after the phone has probed the server - You cannot save the email account configuration unless the probes were successful.
Setup screen 3 - Account settings
Now we can change the incoming port from 993 to 143. Older versions of iOS don't allow that. Newer versions use 993/SSL to mean connect to port 993, open an SSL tunnel, and then talk IMAP thru the tunnel. They use 143/SSL to mean connect to port 143 and negotiate STARTTLS as specified in rfc2592.
16:24:19.299711 IP 205.147.40.48.52697 > 205.147.40.34.993: Flags [S], seq 2439554283, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085977412 ecr 0,sackOK,eol], length 0 16:24:20.994522 IP 205.147.40.48.52699 > 205.147.40.34.993: Flags [S], seq 1716286145, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085979057 ecr 0,sackOK,eol], length 0 16:24:21.954759 IP 205.147.40.48.52700 > 205.147.40.34.993: Flags [S], seq 1109028180, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085979980 ecr 0,sackOK,eol], length 0 16:24:26.195230 IP 205.147.40.48.52704 > 205.147.40.34.993: Flags [S], seq 1601089501, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1085984127 ecr 0,sackOK,eol], length 0 16:25:34.506384 IP 205.147.40.48.52724 > 205.147.40.34.993: Flags [S], seq 1142067416, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1086052208 ecr 0,sackOK,eol], length 0 16:25:55.247891 IP 205.147.40.48.52730 > 205.147.40.34.993: Flags [S], seq 1752631885, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1086072777 ecr 0,sackOK,eol], length 0 16:27:05.655737 IP 205.147.40.48.52743 > 205.147.40.34.143: Flags [S], seq 2536497684, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1086142958 ecr 0,sackOK,eol], length 0 16:27:05.687298 IP 205.147.40.48.52744 > 205.147.40.34.143: Flags [S], seq 2207841639, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1086142998 ecr 0,sackOK,eol], length 0 16:27:12.030907 IP 205.147.40.48.52761 > 205.147.40.34.143: Flags [S], seq 3893396509, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1086149175 ecr 0,sackOK,eol], length 0 16:27:20.809898 IP 205.147.40.48.52764 > 205.147.40.34.143: Flags [S], seq 469468408, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1086157899 ecr 0,sackOK,eol], length 0
Results
The iPhone properly uses IMAP/143/STARTTLS to receive email, and uses SMTP/587/STARTTLS to send email. The raw SSL probe to port 587 should be removed, and I think Apple should try IMAP/143/STARTTLS before trying SSL on port 993.